2. SystemVerilog Function
函数
- 函数是一段可重用的代码,用于执行特定任务。
- 函数可以有输入参数和返回值。
- 函数不能包含时序控制语句(如
#
延迟或@
触发事件)。
函数的基本语法
function [return_type] function_name(input_arguments);
// 函数体
endfunction
返回类型
- 可以是任何数据类型,包括
int
,bit
,logic
,byte
等。 - 如果没有指定返回类型,默认为
int
。
输入参数
- 输入参数可以在函数调用时传递。
- 参数可以是
input
、output
或inout
类型。
Example:
function int add(int a, int b);
return a + b;
endfunction
函数的使用
- 函数通常在模块内部定义,也可以在包中定义以便跨多个模块使用。
- 函数可以在过程块(如
initial
和always
)中调用。
Example:
module tb;
initial begin
int result = add(3, 4); // 调用函数并存储结果
$display("Result = %0d", result); // 输出: Result = 7
end
function int add(int a, int b);
return a + b;
endfunction
endmodule
函数的特性
无时序控制
- 函数内不能使用时序控制语句(如
#
延迟或@
触发事件)。 - 函数必须在单个时间步内完成所有操作。
自动变量
- 函数内的局部变量默认为自动变量(每次调用时重新初始化)。
- 可以使用
static
关键字声明静态变量(在多次调用之间保持状态)。
Example:
function int counter();
static int count = 0; // 静态变量
count++;
return count;
endfunction
函数的返回值
- 使用
return
语句返回一个值。 - 如果没有显式返回值,函数将返回默认值(通常是0)。
Example:
function int max(int a, int b);
if (a > b)
return a;
else
return b;
endfunction
函数的参数
输入参数
- 默认情况下,函数参数是
input
类型。 - 可以显式声明
input
类型。
输出参数
- 使用
output
关键字声明输出参数。 - 输出参数可以在函数体内修改,并在调用后返回。
Example:
function void swap(ref int a, ref int b);
int temp;
temp = a;
a = b;
b = temp;
endfunction
module tb;
initial begin
int x = 10;
int y = 20;
swap(x, y); // 调用函数
$display("x = %0d, y = %0d", x, y); // 输出: x = 20, y = 10
end
endmodule
递归函数
- 函数可以调用自身(递归)。
- 递归函数需要有一个终止条件,否则会导致无限递归。
Example:
function int factorial(int n);
if (n == 0)
return 1;
else
return n * factorial(n - 1);
endfunction
module tb;
initial begin
int result = factorial(5); // 计算 5!
$display("Factorial of 5 is %0d", result); // 输出: Factorial of 5 is 120
end
endmodule
包中的函数
- 函数可以在包中定义,以便在多个模块中重用。
- 包中的函数可以通过导入包来使用。
Example:
package math_pkg;
function int add(int a, int b);
return a + b;
endfunction
endpackage
module tb;
import math_pkg::*;
initial begin
int result = add(3, 4); // 调用包中的函数
$display("Result = %0d", result); // 输出: Result = 7
end
endmodule